package DataBaseQuery;

import java.util.ArrayList;

import DataBaseManager.Field;
import DataBaseManager.Row;
import DataBaseManager.Table;
import DataType.MyDataType;
import DataType.MyDataType.MY_TYPE;

public class RegularView extends View {
	
	boolean isRaw = true;
	
	private ArrayList<Row> rows;
	
	public RegularView(Table table) {

		initFromTable(table);
		for (VariableReference field : fields) {
			field.subTableName = "";
		}
	}


	public RegularView(Table table, String newName) {
		initFromTable(table);
		for (VariableReference field : fields) {
			field.subTableName = newName;
		}
	}

	public void initFromTable(Table table) {
		
		rows = new ArrayList<Row>();
		fields = VariableReference.getVaribleRefFromTable(table);
		for (int i = 0; i < table.getNumberOfRow(); i++) {
			Row row = new Row();

			for (int j = 0; j < table.getFields().size(); j++) {
				row.add(table.getValue(j, i));
			}
			rows.add(row);
		}
	}

	public RegularView() {
		fields = new ArrayList<VariableReference>();
		rows = new ArrayList<Row>();
	}

	public RegularView(int nRow) {
		fields = new ArrayList<VariableReference>();
		rows = new ArrayList<Row>();
		for (int i = 0; i < nRow; i++)
			rows.add(new Row());
	}


	public ArrayList<Row> getRows()
	{
		return rows;
	}
	
	public RegularView mult(RegularView view) {
		RegularView multView = new RegularView();
		multView.fields.addAll(fields);
		multView.fields.addAll(view.fields);

		for (int i = 0; i < rows.size(); i++) {
			for (int j = 0; j < view.rows.size(); j++) {
				Row row = new Row();
				row.addAll(rows.get(i).getValues());
				row.addAll(view.rows.get(j).getValues());
				multView.rows.add(row);
			}
		}
		return multView;
	}


	public RegularView select(ArrayList<MyExpression> fieldsName) {
		ArrayList<MyExpression> selectedFields = new ArrayList<MyExpression>();
		for (MyExpression myExpression : fieldsName) {
			if(myExpression.name.equals("*"))
			{
				for (VariableReference field : fields) {
					selectedFields.add(new MyVarible(field.tableName+"."+field.fieldName));
				}
			}
			else 
			{
				selectedFields.add(myExpression);
			}
		}
		RegularView view = new RegularView();
		int n = selectedFields.size();
		for (int i = 0; i < n; i++) {
			view.fields.add(new VariableReference(name, getFieldName(selectedFields.get(i).name)));
		}
		for(int i=0;i<rows.size();i++)
		{
			Row newRow = new Row();
			setVariableReference(i);
			for (int j = 0; j < n; j++) {
				if(selectedFields.get(j).isValid(this))
					newRow.add(selectedFields.get(j).getValue(this));
				else
					return null;

			}
			view.rows.add(newRow);
		}
		view.isRaw = false;
		return view;

	}
	public void setVariableReference(int rowIndex) {
		for (int i = 0; i < fields.size(); i++) {
			fields.get(i).setValue(rows.get(rowIndex).getValue(i));
			
		}
	}
	public ArrayList<VariableReference> getVariableReference(int rowIndex) {
		ArrayList<VariableReference> varRefs = new ArrayList<VariableReference>();
		setVariableReference(rowIndex);
		varRefs.addAll(fields);
		return varRefs;
	}

	private MyDataType.MY_TYPE getFieldType(int colIndex)
	{
		for (Row row : rows) {
			MyDataType val = row.getValue(colIndex);
			if(val != null && val.getType() != MY_TYPE.MY_NULL)
				return val.getType();
		}
		return MY_TYPE.MY_NULL;
	}
	public Table toTable() {
		Table table = new Table("Temp");
		for (int i=0;i<fields.size();i++) {

			table.getFields().add(
					new Field(fields.get(i).fieldName, getFieldType(i)));
		}
		for (Row row : rows) {
			table.insertData(row);
		}
		return table;
	}
	
	public RegularView choice(Condition con)
	{
		RegularView v = new RegularView();
		v.fields.addAll(fields);
		for(int i=0;i<rows.size();i++)
		{
			/*MyVarible.clearCurrentVarible();
			MyVarible.addCurrentVarible(this.getVariableReference(i));*/
			this.setVariableReference(i);
			/*if (!con.checkInvalidVarible()) {
				return null;
			}*/
			
			if (con.isTrue(this)) {
				v.rows.add(rows.get(i));
			} 
		}
		return v;
	}
	
	public GroupView group(ArrayList<String> fieldNames)
	{
		GroupView view = new GroupView();
		int n = fieldNames.size();
		boolean[] nonGroupedColIndexs = new boolean[fields.size()];
		int[] colIndex = new int[fieldNames.size()];
		for(int i=0;i<fields.size();i++)
		{
			nonGroupedColIndexs[i] = true;
		}	
		for (int i = 0; i < n; i++) {
			int index = getFieldIndex(fieldNames.get(i));
			if (index == -1)
				return null;
			nonGroupedColIndexs[index] = false;
			colIndex[i] = index;
			view.fields.add(fields.get(index));
		}
		ArrayList<VariableReference> nonFields = new ArrayList<VariableReference>();
		for(int i=0;i<fields.size();i++)
		{
			if(nonGroupedColIndexs[i])
			{
				nonFields.add(fields.get(i));
			}
		}	


		for (Row row : rows) {
			Row newRow = new Row();
			Row newNonRow = new Row();		
			for (int i = 0; i < fieldNames.size(); i++)
				{
					newRow.add(row.getValue(colIndex[i]));
				}
			for (int i = 0; i < fields.size(); i++) {
				if(nonGroupedColIndexs[i])
				{
					newNonRow.add(row.getValue(i));
				}

			}
			int groupIndex = view.groupIndex(newRow) ;
			if(groupIndex == -1)
			{
				view.addGroup(new Group(newRow, nonFields));
				view.addToGroup(view.size()-1, newNonRow);
			}
			else
			{
				view.addToGroup(groupIndex, newNonRow);
			}
		}
		
		return view;
	}
}
